package com.lap.context.starter.core.interceptor;

import com.lap.context.starter.autoconfigure.properties.HeaderProperties;
import com.lap.context.starter.entity.HeaderInfo;
import com.lap.context.starter.entity.UserInfo;
import com.lap.context.starter.handler.UserHandler;
import com.lap.context.starter.shared.Constant;
import com.lap.context.starter.shared.HeaderUtil;
import com.lap.framework.common.constant.Header;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

@Slf4j
public class UserInterceptor implements HandlerInterceptor {

  @Resource private HeaderProperties properties;

  @Override
  public boolean preHandle(
      @NonNull HttpServletRequest request,
      @NonNull HttpServletResponse response,
      @NonNull Object handler) {
    Integer userId = HeaderUtil.getUserId(request);
    // 可能需要没有用户时候抛出异常
    HeaderInfo userInfo =
        UserInfo.builder()
            .userId(userId)
            .userName(HeaderUtil.getUserName(request))
            .fullName(HeaderUtil.getFullName(request))
            .tenantCode(HeaderUtil.getStr(request, Header.TENANT_CODE, Constant.TENANT_CODE))
            .map(customizer(request))
            .build();

    UserHandler.set(userInfo);

    if (Objects.equals(userId, Constant.USER_ID)) {
      log.warn("获取用户信息失败，请注意检查头信息");
    }
    log.info("Lap context starter user info ::{}", userInfo);

    return true;
  }

  protected Map<String, String> customizer(HttpServletRequest request) {
    if (Objects.isNull(properties) || CollectionUtils.isEmpty(properties.getParameters())) {
      return Collections.emptyMap();
    }

    Map<String, String> result = new HashMap<>(properties.getParameters().size());
    for (HeaderProperties.Prop prop : properties.getParameters()) {
      String value = HeaderUtil.getStr(request, prop.getKey(), prop.isEncode(), null);
      if (StringUtils.isNotBlank(value)) {
        result.put(prop.getKey(), value);
      }
    }
    return result;
  }

  @Override
  public void afterCompletion(
      @NonNull HttpServletRequest request,
      @NonNull HttpServletResponse response,
      @NonNull Object handler,
      Exception ex) {
    UserHandler.remove();
  }
}
